package com.aneliya.server.dispatcher;

import java.util.Vector;

import com.aneliya.client.IClient;
import com.aneliya.model.Message;
import com.aneliya.model.MessageType;

public class Dispatcher extends Thread {
	private Vector<Message> messageQueue = new Vector<Message>();
	private Vector<IClient> clients = new Vector<IClient>();
	
	public synchronized Boolean isClientAuthenticated(IClient client) {
		Boolean result = clients.indexOf(client) != -1;
		return result;
	}
	
	public synchronized void addClient(IClient client) {
		clients.add(client);
		dispatchUserLoginMessage(client.getUsername());
		notifyClientForOnlineUsers(client);
	}
	
	private void notifyClientForOnlineUsers(IClient client) {
		for (IClient authenticatedClient : clients) {
			if (authenticatedClient != client) {
				Message message = new Message(authenticatedClient.getUsername(), null);
				message.setMessageType(MessageType.LOGIN);
				
				client.sendMessage(message);
			}
		}
	}

	public synchronized void removeClient(IClient client) {
		int clientIndex = clients.indexOf(client);
		if (clientIndex != -1) {
			clients.remove(clientIndex);
			dispatchUserLogoutMessage(client.getUsername());
			client.setUsername(null);
		}
	}
	
	public synchronized void dispatchMessage(Message message) {
		messageQueue.add(message);
		notify();
	}
	
	private void dispatchUserLoginMessage(String username) {
		Message loginMessage = new Message(username, null);
		loginMessage.setMessageType(MessageType.LOGIN);
		dispatchMessage(loginMessage);
	}
	
	private void dispatchUserLogoutMessage(String username) {
		Message logoutMessage = new Message(username, null);
		logoutMessage.setMessageType(MessageType.LOGOUT);
		dispatchMessage(logoutMessage);
	}
	
	private synchronized Message getNextMessageFromQueue() throws InterruptedException {
		while (messageQueue.size() == 0) {
			wait();
		}
		Message message = messageQueue.firstElement();
		messageQueue.remove(0);
		return message;
	}
	
	private void sendMessageToAllClients(Message message) {
		for (IClient client : clients) {
			client.sendMessage(message);
		}
	}
	
	public void run() {
		try {
			while (true) {
				Message message = getNextMessageFromQueue();
				sendMessageToAllClients(message);
			}
		} catch (InterruptedException e) {
			// The thread is interrupted and it stops its execution
		}
	}
}
